//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2005-2007
//
// Object properties dialog - 'Track' page.
//

# include "StdAfx.h"
# include "Resource.h"
# include "RgnProperties.h"
# include "PropertyPages.h"
# include "Map.h"
# include "MapView.h"
# include "Types.h"
# include "Rename.h"
# include "SetComment.h"
# include "ShowRgnOnMap.h"
# include "AltProfile.h"
# include "PrintUnits.h"
# include "Static.h"
# include "Button.h"
# include "fast_floor.h"
# include "Settings.h"
# include "Globals.h"

bool CTrackPage::OnInit (HWND _hwndFocus) {
	// Label.
	SetDlgItemText (IDC_LABEL,   m_rgn.strLabel.c_str ());

	// Description.
	SetDlgItemText (IDC_COMMENT, m_rgn.strComment.c_str ());

	track_info_t * const pTrkExtra = m_rgn.pExtra ? m_rgn.pExtra->wtr.track () : NULL;
	const trackpoints_t & TrackPoints = m_rgn.elements [0].pExtra->TrackPoints;

	// Link.
	if (pTrkExtra) {
		if (pTrkExtra->strURL.empty ())
			EnableDlgItem (IDC_LINK_BROWSE, false);
		else
			SetDlgItemText (IDC_LINK, pTrkExtra->strURL.c_str ());
	}
	SetButtonIcon (m_hWnd, IDC_LINK_BROWSE, IDI_BROWSE);

	if (! m_rgn.elements.empty ()) {
		const rgn_element_t & element0 = m_rgn.elements [0];
		const points_t & points = element0.points;

		// Points.
		SetDlgItemUInt (IDC_POINTS, points.size ());

		// Elapsed time.
		double fElapsedTime = 0;
		if (
			! TrackPoints.empty () &&
			TrackPoints [0                      ].wFlags & trackpoint_info_t::defTime &&
			TrackPoints [TrackPoints.size () - 1].wFlags & trackpoint_info_t::defTime
		) {
			fElapsedTime = (TrackPoints [TrackPoints.size () - 1].dtTime - TrackPoints [0].dtTime)*24*60*60;
			if (fElapsedTime > 0) {
				const int nSecond = fast_floor_d (fElapsedTime + .5);
				const int nMinute = nSecond/60;
				const int nHour   = nMinute/60;

				SetDlgItemTextF (IDC_ELAPSED_TIME, "%02d:%02d:%02d", nHour, nMinute - nHour*60, nSecond - nMinute*60);
			} else
				fElapsedTime = 0;
		}

		// Length.
		const float fLength = GetLength (points)*40e6/360;
		char strDistance [32];
		char strDistanceUnit [16];
		PrintDistance (strDistance, strDistanceUnit, fLength);
		SetDlgItemTextF (IDC_LENGTH, "%s %s", strDistance, strDistanceUnit);

		// Average speed.
		double fAveSpeed = 0;
		bool bAveSpeedDefined = false;
		if (fElapsedTime > 0) {
			fAveSpeed = 3.6*fLength/fElapsedTime;
			bAveSpeedDefined = true;
		} else {
			const size_t cExtraPoints = TrackPoints.size ();
			size_t cN = 0;
			for (size_t c = 0; c < cExtraPoints; ++ c) {
				if (TrackPoints [c].wFlags & trackpoint_info_t::defSpeed) {
					fAveSpeed += TrackPoints [c].fSpeed;
					++ cN;
				}
			}
			if (cN > 0) {
				fAveSpeed /= cN;
				bAveSpeedDefined = true;
			}
		}

		if (bAveSpeedDefined) {
			char strAveSpeed [32];
			char strSpeedUnits [16];
			PrintSpeed (strAveSpeed, strSpeedUnits, fAveSpeed);
			SetDlgItemTextF (IDC_AVERAGE_SPEED, "%s %s", strAveSpeed, strSpeedUnits);
		}

		// Area.
		const float fCosY = element0.rectBound.Empty () ? 1 : ::cos (element0.rectBound.MeanY ()*c_PI/180);
		char strArea [32];
		char strAreaUnits [16];
		PrintArea (strArea, strAreaUnits, GetArea (points)*40e6*40e6/360/360*fCosY);
		SetDlgItemTextF (IDC_AREA, "%s %s", strArea, strAreaUnits);
	}

	// Altitude profile.
	EnableDlgItem (IDC_ALT_PROFILE, IsAltitudeProfileDefined (m_rgn));

	return true;
}

void CTrackPage::OnCommand (WORD _wCmd, WORD _wNotifyCode, HWND _hwndCtl) {
	switch (_wCmd) {
		case IDC_LINK_BROWSE: {
			char strWebLink [256];
			GetDlgItemText (IDC_LINK, strWebLink, sizeof (strWebLink)/sizeof (strWebLink [0]));
			::ShellExecute (m_hWnd, NULL, strWebLink, NULL, NULL, SW_SHOWNORMAL);
			break;
		}

		case IDC_SHOW_ON_MAP:
			ShowRgnOnMap (m_rgn);
			break;

		case IDC_LABEL:
		case IDC_COMMENT:
		case IDC_LINK:
			if (_wNotifyCode == EN_UPDATE)
				PropSheetChanged ();
			break;

		case IDC_ALT_PROFILE:
			ShowAltitudeProfile (m_hWnd, m_rgn);
			break;
	}
}

void CTrackPage::OnApply (const PSHNOTIFY *) {
	// Label.
	const HWND hLabel = GetDlgItem (IDC_LABEL);
	const size_t cLabelLen = ::GetWindowTextLength (hLabel);
	char * const strLabel = reinterpret_cast<char *> (alloca (cLabelLen + 1));
	::GetWindowText (hLabel, strLabel, cLabelLen + 1);
	if (! (m_rgn.strLabel == strLabel))
		RenameObject (m_rgn, strLabel);

	// Comment.
	const HWND hComment = GetDlgItem (IDC_COMMENT);
	const size_t cCommentLen = ::GetWindowTextLength (hComment);
	char * const strComment = reinterpret_cast<char *> (alloca (cCommentLen + 1));
	::GetWindowText (hComment, strComment, cCommentLen + 1);
	if (! (m_rgn.strComment == strComment))
		SetComment (m_rgn, strComment);

	RefreshRequired ();
}
